﻿using System.Reflection;
using Helper;

namespace CSharpBasic;

public class ReflectionOperationsBase
{
    public virtual void VirtualFunc_1()
    {
        HelperTools.Console_WriteLine_ChangeColor(ConsoleColor.Yellow, "[ReflectionOperationsBase] VirtualFunc_1 no param");
    }
    public virtual void VirtualFunc_2()
    {
        HelperTools.Console_WriteLine_ChangeColor(ConsoleColor.Yellow, "[ReflectionOperationsBase] VirtualFunc_2 no param");
    }
}

public class ReflectionOperations : ReflectionOperationsBase
{
    public static void Main()
    {
        // 通过反射执行方法
        // 1、静态方法
        typeof(ReflectionOperations).GetMethod("StaticMain", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, null);
        // 2、类方法
        // 1)先获取对类的元数据的访问 Type
        Type _type = typeof(ReflectionOperations);
        
        // 2)先获取构造方法数据 ConstructorInfo
        Type[] _types = Array.Empty<Type>();
        _types = new Type[0];
        _types = new Type[] { };
        _types = Type.EmptyTypes;
        ConstructorInfo _constructorInfo = _type.GetConstructor(_types);
        
        // 3)接收执行构造函数(无参)返回的对象
        object _classObject = _constructorInfo.Invoke(new object[]{});
        // 4)通过反射获取要执行的方法(无参)对象 MethodInfo
        MethodInfo _methodInfo = _type.GetMethod("ReflectionTest", new Type[]{});
        // 执行无参方法, 参数1：传入构造方法执行返回的对象
        _methodInfo.Invoke(_classObject, new object[] { });
        
        // 执行有参数方法, 要传入参数的类型列表：new Type[]{ typeof(int) }
        MethodInfo _methodInfoHaveParam = _type.GetMethod("ReflectionTest", new Type[]{ typeof(int) });
        object result = _methodInfoHaveParam.Invoke(_classObject, new object[] { 1 });
        
        MethodInfo _methodInfo_3 = _type.GetMethod("ReflectionTest", new Type[]{typeof(int), typeof(string)});
        _methodInfo_3.Invoke(_classObject, new object[] { 1, "123" });

        // 继承的反射: 
        MethodInfo _methodInfo_4 = _type.GetMethod("VirtualFunc_1", new Type[]{});
        _methodInfo_4.Invoke(_classObject, new object[] { });
        MethodInfo _methodInfo_5 = _type.GetMethod("VirtualFunc_2", new Type[]{});
        _methodInfo_5.Invoke(_classObject, new object[] { });
    }

    private int param;

    public ReflectionOperations()
    {
    }

    public ReflectionOperations(int param)
    {
        this.param = param;
    }

    static void StaticMain()
    {
        HelperTools.Console_WriteLine_ChangeColor(ConsoleColor.Blue, "StaticMain");
    }

    public void ReflectionTest()
    {
        HelperTools.Console_WriteLine_ChangeColor(ConsoleColor.DarkRed, "ReflectionTest no param");
    }
    
    public int ReflectionTest(int cnt)
    {
        HelperTools.Console_WriteLine_ChangeColor(ConsoleColor.Green, "ReflectionTest have param");
        return 1;
    }
    public void ReflectionTest(int cnt, string str)
    {
        HelperTools.Console_WriteLine_ChangeColor(ConsoleColor.Green, "ReflectionTest have param: int, string");
    }
    
    public override void VirtualFunc_2()
    {
        HelperTools.Console_WriteLine_ChangeColor(ConsoleColor.Yellow, "VirtualFunc_2 no param");
    }
}